#include "uart_tool.h"
#include "ui_uart_tool.h"
#include <QMessageBox>


uart_tool::uart_tool(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::uart_tool)
{
    ui->setupUi(this);
    resize(800, 600);

    serial_test = new QSerialPort(this);//串口对象
    this->setAttribute(Qt::WA_QuitOnClose, false);//子窗口设置为false,这样主窗口关闭，所有子窗口都关闭
    timer = new QTimer(this);

    connect(timer, &QTimer::timeout, this, &uart_tool::readData);//定时器中断处理函数配置
    ui->radioButton_send_char->setChecked(true);
}

uart_tool::~uart_tool()
{
    if(serial_test->isOpen())//debug 加上这行就崩溃  串口关闭)
    {
        serial_test->close();//debug 加上这行就崩溃  串口关闭
    }

    delete serial_test;
    delete ui;
    delete timer;
}
//清空接收缓冲区
void uart_tool::on_pushButton_clear_recv_clicked()
{
    ui->textEdit_recv_data->clear();//接收缓冲区文本框清空
    SendByte = 0;
    ReceByte = 0;

    ui->label_rx_count->setText("RX:" + QString::number(SendByte));//清空接收字节数
    ui->label_tx_count->setText("TX:" + QString::number(ReceByte));//清空发送字节数

}

//清空发送缓冲区
void uart_tool::on_pushButton_clear_send_clicked()
{
    ui->textEdit_send_data->clear();//清空发送文本框
}


void uart_tool::on_pushButton_scan_uart_clicked()
{
    int i = 0;
    int n = 0;

    ui->comboBox_uart_name->clear();//串口列表清空
    serialPortName.clear();//串口名称清空

    foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts()) {

        qDebug() << info.description()  << info.portName();//打印串口信息和串口名称
        if(!info.description().contains("serial port emulator"))//虚拟串口不算在内
        {
            serialPortName.append(info.portName());
        }
    }

    n = serialPortName.size();

    for(i = 0; i < n; i++)
    {
        serial_test->setPortName(serialPortName[i]);//设置串口名称
        if(!serial_test->open(QIODevice::ReadWrite))//打开串口
        {
            serialPortName[i]+="(不可用)";
        }
        else
        {
            serialPortName[i]+="(可用)";
        }

        serial_test->close();//debug 加上这行就崩溃  串口关闭
    }
    ui->comboBox_uart_name->addItems(serialPortName);//将有效的串口名称添加到下拉框
}

void uart_tool::on_pushButton_open_close_clicked()
{
    QString button_name = ui->pushButton_open_close->text();
    if(button_name == "连接")
    {
        // 获取当前选中的文本
        QString currentText = ui->comboBox_uart_name->currentText();
        // 删除 "(可用)"（如果存在）
        if (currentText.endsWith("(可用)")) {
            currentText.remove("(可用)");
        }

        serial_test->setPortName(currentText);//设置串口名称
        if (!serial_test->open(QIODevice::ReadWrite))
        {
            QMessageBox::critical(this, "错误", "无法打开串口！");
            return;
        }
        int baud = ui->comboBox_uart_bsp->currentText().toInt();
        serial_test->setBaudRate(baud);
        // serial_test->setBaudRate(QSerialPort::Baud9600);

        int databits_int = ui->comboBox_uart_data_bites->currentText().toInt();
        QSerialPort::DataBits databits = static_cast<QSerialPort::DataBits>(databits_int);
        serial_test->setDataBits(databits);

        int check_bites_int = ui->comboBox_uart_check_bites->currentIndex();
        if(check_bites_int > 0)
        {
            check_bites_int += 1;
        }
        QSerialPort::Parity check_bites = static_cast<QSerialPort::Parity>(check_bites_int);
        serial_test->setParity(check_bites);

        int stop_bites_int = ui->comboBox_uart_stop_bites->currentIndex() + 1;
        QSerialPort::StopBits stop_bites = static_cast<QSerialPort::StopBits>(stop_bites_int);
        serial_test->setStopBits(stop_bites);

        int flowcontrol_int = ui->comboBox_uart_flow_control->currentIndex();
        QSerialPort::FlowControl flowcontrol = static_cast<QSerialPort::FlowControl>(flowcontrol_int);
        serial_test->setFlowControl(flowcontrol);

        ui->pushButton_open_close->setText("断开"); // 如果当前是"连接"，改为"断开"
        ui->pushButton_open_close->setStyleSheet("QPushButton { background-color: #F44336; color: black; }"); // 红色

        // 启动定时器
        timer->start(10);// 启动定时器 10ms一次

        on_pushButton_clear_recv_clicked();
    }
    else if(button_name == "断开")
    {
        ui->pushButton_open_close->setText("连接"); // 如果当前是"断开"，改为"连接"
        ui->pushButton_open_close->setStyleSheet("QPushButton { background-color: #4CAF50; color: black; }"); // 绿色
        serial_test->close();//debug 加上这行就崩溃  串口关闭
        uart_tool::on_pushButton_clear_recv_clicked();
    }
}


void uart_tool::on_pushButton_send_clicked()
{
    QByteArray sendData = "Hello, Serial Port!";
    QString data = ui->textEdit_send_data->toPlainText();

    /*
    QString message = "Hello, Serial Port!";
    QByteArray data = message.toUtf8();  // 转换为字节数组（UTF-8 编码）
    serial->write(data);                 // 发送数据

    QByteArray hexData = QByteArray::fromHex("A0B1C2");  // 发送 A0 B1 C2
    serial->write(hexData);
    */

    if(ui->radioButton_send_char->isChecked())
    {
        if(ui->radioButton_send_enter->isChecked())// 是否自动换行
        {
            data += "\r\n";
        }
        serial_test->write(data.toUtf8());  // 发送数据 字符串格式
        qDebug() << "要发送的内容：" << data;

        if(ui->radioButton_timestap->isChecked())// 是否加时间戳
        {
            QString inster_data;
            inster_data += "send ";
            inster_data += QDateTime::currentDateTime().toString("[yyyy-MM-dd HH:mm:ss.zzz]:");
            ui->textEdit_recv_data->moveCursor(QTextCursor::End);  // 移动光标到末尾
            // 插入红色文本
            //ui->textEdit->append("<span style='color:red;'>这是红色文本</span>");
            // 插入带颜色的文本（保持原有内容）
            //ui->textEdit->insertHtml("<font color='blue'>这是蓝色文本</font><br>");
            // 组合使用
            QString coloredText = QString("<span style='color:%1;'>%2</span>")
                                      .arg("green")  // 颜色
                                      .arg(inster_data);  // 文本内容
            ui->textEdit_recv_data->append(coloredText);
        }
        ui->textEdit_recv_data->moveCursor(QTextCursor::End);  // 移动光标到末尾
        ui->textEdit_recv_data->insertPlainText(data);  // 插入文本
        // ui->textEdit_recv_data->insertPlainText("\n");         // 换行

        SendByte += data.size();
        ui->label_tx_count->setText("TX:" + QString::number(ReceByte));//发送字节数
    }
    else if(ui->radioButton_send_hex->isChecked()) //输入的是 16进制字符串（例如 "A0 B1 C2" 或 "A0B1C2"）
    {
        // 移除所有空格和换行符
        data = data.simplified().replace(" ", "");
        // 检查是否为有效的16进制字符串
        if (data.isEmpty() || data.length() % 2 != 0) {
            QMessageBox::warning(this, "错误", "无效的16进制数据！");
            return;
        }

        // 转换为16进制字节数组
        QByteArray hexData = QByteArray::fromHex(data.toLatin1());

        // 检查转换是否成功
        if (hexData.isEmpty()) {
            QMessageBox::warning(this, "错误", "16进制数据转换失败！");
            return;
        }

        if(ui->radioButton_send_enter->isChecked())// 是否自动换行
        {
            hexData.append(0x0D);
            hexData.append(0x0A);
        }

        serial_test->write(hexData);  // 发送数据


        SendByte += hexData.size();
        ui->label_tx_count->setText("TX:" + QString::number(ReceByte));//发送字节数


        if(ui->radioButton_timestap->isChecked())// 是否加时间戳
        {
            QString inster_data;
            inster_data += "send ";
            inster_data += QDateTime::currentDateTime().toString("[yyyy-MM-dd HH:mm:ss.zzz]:");
            ui->textEdit_recv_data->moveCursor(QTextCursor::End);  // 移动光标到末尾
            // 组合使用
            QString coloredText = QString("<span style='color:%1;'>%2</span>")
                                      .arg("green")  // 颜色
                                      .arg(inster_data);  // 文本内容
            ui->textEdit_recv_data->append(coloredText);
        }

        ui->textEdit_recv_data->moveCursor(QTextCursor::End);  // 移动光标到末尾
        ui->textEdit_recv_data->insertPlainText(hexData.toHex(' ').toUpper());  // 插入文本
        //ui->textEdit_recv_data->insertPlainText("\n");         // 换行

        QString print_data;

        for (int i = 0; i < hexData.size(); ++i) {
            print_data += QString("%1 ").arg((quint8)hexData.at(i), 2, 16, QChar('0')).toUpper();
        }
        qDebug() << "要发送的内容：" << print_data;
    }

    if (!serial_test->waitForBytesWritten(1000)) {  // 等待写入完成（超时1秒）
        qDebug() << "写入超时！";
    }
}

// 串口定时收取数据
void uart_tool::readData()
{
    if(!serial_test->isOpen())
    {
        return;
    }

    // 读取所有可用数据
    QByteArray data = serial_test->readAll();

    ReceByte += data.size();
    ui->label_tx_count->setText("TX:" + QString::number(ReceByte));//清空发送字节数

    // 如果数据不为空，处理数据
    if (!data.isEmpty())
    {
        if(ui->radioButton_recv_show_char->isChecked())
        {
            qDebug() << "Received data:" << data;  // 字符串格式


            if(ui->radioButton_timestap->isChecked())// 是否加时间戳
            {
                QString inster_data ;
                inster_data += " recv ";
                inster_data += QDateTime::currentDateTime().toString("[yyyy-MM-dd HH:mm:ss.zzz]:");
                ui->textEdit_recv_data->moveCursor(QTextCursor::End);  // 移动光标到末尾
                // 组合使用
                QString coloredText = QString("<span style='color:%1;'>%2</span>")
                                          .arg("red")  // 颜色
                                          .arg(inster_data);  // 文本内容
                ui->textEdit_recv_data->append(coloredText);
            }

            ui->textEdit_recv_data->moveCursor(QTextCursor::End);  // 移动光标到末尾
            ui->textEdit_recv_data->insertPlainText(data);  // 插入文本
            ui->textEdit_recv_data->insertPlainText("\n");         // 换行
        }
        else if(ui->radioButton_recv_show_hex->isChecked()) //输入的是 16进制字符串（例如 "A0 B1 C2" 或 "A0B1C2"）
        {
            qDebug() << "Received data:" << data.toHex(' ').toUpper();  // 以16进制格式输出 大写
            QString inster_data;

            if(ui->radioButton_timestap->isChecked())// 是否加时间戳
            {
                inster_data += " recv ";
                inster_data += QDateTime::currentDateTime().toString("[yyyy-MM-dd HH:mm:ss.zzz]:");
            }
            ui->textEdit_recv_data->moveCursor(QTextCursor::End);  // 移动光标到末尾
            ui->textEdit_recv_data->insertPlainText(data.toHex(' ').toUpper());  // 插入文本
            ui->textEdit_recv_data->insertPlainText("\n");         // 换行
        }

        // 自动滚动到底部
        if(ui->radioButton_recv_auto_roll->isChecked())//是否自动滚动
        {
            QScrollBar *scrollBar = ui->textEdit_recv_data->verticalScrollBar();
            scrollBar->setValue(scrollBar->maximum());
        }
    }
}


void uart_tool::on_radioButton_send_char_clicked()
{

}

